package com.emperor.misc.app;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;

import com.emperor.cashier.app.CashierAppCtrl;
import com.emperor.core.app.App;
import com.emperor.core.app.AppBase;
import com.emperor.core.app.AppConstant;
import com.emperor.employee.logic.Employee;
import com.emperor.employee.logic.EmployeeModel;
import com.emperor.user.logic.User;
import com.emperor.user.logic.UserModel;
import com.emperor.util.HibernateUtil;
import com.swtdesigner.SWTResourceManager;
import org.eclipse.swt.widgets.Composite;

public class LoginAppForm extends AppBase implements App {

	private Button exitButton;
	private Button loginButton;
	private Button fullScreenButton;
	private Text txtPassword;
	private Combo usernameCombo;
	protected Shell shell;
	public static Logger log = Logger.getLogger(LoginAppForm.class);

	public LoginAppForm() {
		super();
	}

	public LoginAppForm(Map<String, Object> params) {
		super();
		this.params = params;
	}

	/**
	 * Launch the application
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			LoginAppForm window = new LoginAppForm();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window
	 */
	public void open() {
		final Display display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
	}

	/**
	 * Create contents of the window
	 */
	protected void createContents() {
		shell = new Shell();
		shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
		shell.setImage(SWTResourceManager.getImage(LoginAppForm.class,
				"/img/iMac OSX.png"));
		shell.setBackgroundImage(SWTResourceManager.getImage(
				LoginAppForm.class, "/img/login.jpg"));
		shell.setSize(1280, 800);
		shell.setText("Login");

		centreShell(shell);
		shell.setMaximized(true);

		final Label userNameLabel = new Label(shell, SWT.NONE);
		userNameLabel.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		userNameLabel.setText("User Name");
		userNameLabel.setBounds(496, 342, 96, 20);

		final Label passwordLabel = new Label(shell, SWT.NONE);
		passwordLabel.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		passwordLabel.setText("Password");
		passwordLabel.setBounds(496, 391, 86, 20);

		txtPassword = new Text(shell, SWT.BORDER | SWT.PASSWORD);
		txtPassword.addKeyListener(new KeyAdapter() {
			public void keyPressed(final KeyEvent e) {
				if (e.character == SWT.LF || e.character == SWT.CR) {
					doLogin(usernameCombo.getText(), txtPassword.getText());
				}
			}
		});
		txtPassword.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		txtPassword.setBounds(611, 388, 249, 30);

		fullScreenButton = new Button(shell, SWT.CHECK);
		fullScreenButton.setVisible(false);
		fullScreenButton.setSelection(true);
		fullScreenButton.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));
		fullScreenButton.setText("Full Screen");
		fullScreenButton.setBounds(346, 504, 105, 20);

		usernameCombo = new Combo(shell, SWT.NONE);
		usernameCombo.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		usernameCombo.setBounds(611, 339, 249, 28);

		loginButton = new Button(shell, SWT.NONE);
		loginButton.setImage(SWTResourceManager.getImage(LoginAppForm.class,
				"/img/Login.png"));
		loginButton.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		loginButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				doLogin(usernameCombo.getText(), txtPassword.getText());
			}
		});
		loginButton.setText("Login");
		loginButton.setBounds(611, 432, 75, 30);

		exitButton = new Button(shell, SWT.NONE);
		exitButton.setImage(SWTResourceManager.getImage(LoginAppForm.class,
				"/img/Symbol-Delete.png"));
		exitButton.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		exitButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				getParams().put(AppConstant.ONLINE, new Boolean(false));
				getShell().close();
			}
		});
		exitButton.setText("Exit");
		exitButton.setBounds(692, 432, 65, 30);

		final Label pleaseKeyInLabel = new Label(shell, SWT.NONE);
		pleaseKeyInLabel.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 14, SWT.NORMAL));
		pleaseKeyInLabel.setText("Please key in your user name and password");
		pleaseKeyInLabel.setBounds(496, 303, 375, 30);

		//
		doPopulateCombo(usernameCombo);
		shell.setTabList(new Control[] { usernameCombo, txtPassword,
				fullScreenButton, loginButton, exitButton });
	}

	public Shell getShell() {
		return shell;
	}

	public void setShell(Shell shell) {
		this.shell = shell;
	}

	private void doLogin(String username, String password) {
		Map<String, Object> params = getParams();
		if (params != null) {
			User user = authenticate(username, password);
			if (user != null) {
				params.put(AppConstant.USER, user);
				params.put(AppConstant.FULL_SCREEN, fullScreenButton
						.getSelection());
				params.put(AppConstant.APPCTRL, CashierAppCtrl.CASHIER_CTRL);
				params.put(AppConstant.ACTION, CashierAppCtrl.CASHIER_FORM);
				shell.close();
			} else {
				message(getShell(), "Login Error.",
						"Invalid username and password.", SWT.ICON_ERROR
								| SWT.OK);
			}
		} else {
			log.error("Param is null");
		}
	}

	private User authenticate(String username, String password) {
		User user = null;
		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.beginTransaction();
			user = (User) session.createCriteria(UserModel.class).add(
					Expression.eq(User.FLD_USERNAME, username)).add(
					Expression.eq(User.FLD_PASSWORD, password)).uniqueResult();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}

		return user;
	}

	private void doPopulateCombo(Combo combo) {
		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.beginTransaction();
			List<User> users = session.createCriteria(UserModel.class).add(
					Expression.eq(User.FLD_STATUS, AppConstant.STATUS_ACTIVE))
					.list();
			if (users != null && !users.isEmpty()) {
				combo.removeAll();
				for (Iterator<User> iter = users.iterator(); iter.hasNext();) {
					User user = iter.next();
					combo.add(user.getUsername());
				}
			}
		} catch (Exception e) {
			log.error("Unable to populate combo.", e);
		}
	}
}
